<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // ****深拷贝****
    // var a = 111;
    // var b = a;
    // b = 222;
    // console.log(a, b);
    // 1、json方法实现
    function deepClone(obj) {
        let tmp = JSON.stringify(obj);
        let result = JSON.parse(tmp);
        return result;
    }
    var object1 = {
        my: {
            age: 20,
            name: 'luojianming',
            a: undefined,
            b: null,
            c: Symbol('luo'),
            d: function () {

            },
            e: new Date(),
            f: new RegExp(/\d/g)
        },
        you: {
            age: 18,
            name: "luo"
        }
    };
    var object2 = deepClone(object1);
    object2.my.age = 100;
    console.log(object1, object2);

    // 2.for...in 遍历和复制(普通递归)
    // function deepClone(obj) {
    //     // let result = typeof obj.splice == 'function' ? [] : {};
    //     let result = Array.isArray(obj) ? [] : {};
    //     if (obj && typeof obj == 'object') {
    //         for (let i in obj) {
    //             if (obj[i] && typeof obj[i] == 'object') {
    //                 result[i] = deepClone(obj[i]);
    //             } else {
    //                 result[i] = obj[i];
    //             }
    //         }
    //         return result;
    //     }
    //     return obj;
    // }
    // let arr1 = [1, 2, 3, 4, 5];
    // let arr2 = deepClone(arr1);
    // arr1[1] = 999;
    // arr2[2] = 1000;
    // console.log(arr1, arr2);
    // let obj1 = {
    //     name: '张三',
    //     age: 18,
    //     family: {
    //         brother: '李四',
    //         father: '刘二',
    //         mother: '王五'
    //     }
    // }
    // let obj2 = deepClone(obj1);
    // obj2.family.father = '王一';
    // console.log(obj1, obj2);

    // 3.防栈溢出递归函数
    // function cloneLoop(x) {
    //     const root = {};

    //     // 栈
    //     const loopList = [
    //         {
    //             parent: root,
    //             key: undefined,
    //             data: x,
    //         }
    //     ];

    //     while (loopList.length) {
    //         // 深度优先
    //         const node = loopList.pop();
    //         const parent = node.parent;
    //         const key = node.key;
    //         const data = node.data;

    //         // 初始化赋值目标，key为undefined则拷贝到父元素，否则拷贝到子元素
    //         let res = parent;
    //         if (typeof key !== 'undefined') {
    //             res = parent[key] = {};
    //         }

    //         for (let k in data) {
    //             if (data.hasOwnProperty(k)) {
    //                 if (typeof data[k] === 'object') {
    //                     // 下一次循环
    //                     loopList.push({
    //                         parent: res,
    //                         key: k,
    //                         data: data[k],
    //                     });
    //                 } else {
    //                     res[k] = data[k];
    //                 }
    //             }
    //         }
    //     }
    //     return root;
    // }

    // function deepClone(obj, map = new Map()) {
    //     if (typeof obj !== 'object' || obj == null) {
    //         return obj;
    //     }
    //     console.log(map);
    //     if (map.get(obj)) {
    //         return map.get(obj);
    //     }
    //     let result = Array.isArray(obj) ? [] : {};
    //     map.set(obj, result);
    //     for (let i in obj) {
    //         if (obj.hasOwnProperty(i)) {

    //             result[i] = deepClone(obj[i], map);
    //         } else {
    //             result[i] = obj[i];
    //         }
    //     }
    //     return result;
    // }

    // let obj1 = {
    //     name: '张三',
    //     age: 18,
    //     family: {
    //         brother: '李四',
    //         father: '刘二',
    //         mother: '王五'
    //     }
    // }
    // let obj2 = deepClone(obj1);
    // obj2.family.father = '王一';

    // console.log(obj1, obj2);



    // *利用Object.create()进行copy,对象中嵌套的对象无法深拷贝
    // let deepClone = function (obj) {
    //     let copy = Object.create(Object.getPrototypeOf(obj));
    //     let propNames = Object.getOwnPropertyNames(obj);
    //     propNames.forEach(function (items) {
    //         let item = Object.getOwnPropertyDescriptor(obj, items);
    //         Object.defineProperty(copy, items, item);
    //     });
    //     return copy;
    // }

    // ****浅拷贝****
    // var obj1 = {
    //     name: 'luo',
    //     age: 18
    // }
    // obj1和obj2指向同一内存地址，obj2改变会改变obj1的值
    // var obj2 = obj1;
    // obj2.name = 111;
    // console.log(obj1, obj2);

    // Object.assign()拷贝的对象属性值为简单类型为深拷贝，拷贝的对象属性值为引用类型为浅拷贝(只能深拷贝一层对象)
    let arr = [];
    let arr1 = [1, 2, 3, 4];
    Object.assign(arr, arr1);
    var res = arr1.push(8);//返回一个新的数组长度
    console.log(res);
    console.log(arr, arr1);



    // 递归深拷贝
    function deepClone(obj) {
        if (typeof obj !== 'object' || obj == null) {
            return obj;
        }

        let result = Array.isArray(obj) ? [] : {};

        for (let i in obj) {
            if (obj.hasOwnProperty(i)) {
                if (typeof obj[i] === 'object') {
                    result[i] = deepClone(obj[i]);
                } else {
                    result[i] = obj[i];
                }
            }
        }
        return result;
    }
    let obj1 = {
        name: '张三',
        age: 18,
        family: {
            brother: '李四',
            father: '刘二',
            mother: '王五'
        }
    }
    let obj2 = deepClone(obj1);
    obj2.family.father = '王一';
    console.log(11111);
    console.log(obj1, obj2);


</script>

</html>